/*
 * Copyright (C) Francisco Morero Peyrona. All rights reserved.
 *
 * This software is published under the terms of Open Source
 * License version 1.1, a copy of which has been included with this
 * distribution in the License.txt file.
 */

package jdbcmanager.dbtools.datatypes;

import java.util.*;

/**
 * This class is an structure of data that represents an Index.
 * <p>
 * It contains all information regarding an index table; among other things, a set of
 * instances of <code>IndexColumnDefinition</code>
 *
 * @author Francisco Morero Peyrona
 */
public final class IndexDefinition extends DbEntityDefinition
{
   private String  sTableName;
   private Vector  vColumn;     // Instances of IndexColumnDefinition

   /**
    * Argument zero class constructor
    */
   public IndexDefinition()
   {
      this( null );
   }

   /**
    * Class constructor
    * 
    * @param td An instance of <code>DbEntityDescriptor</code>
    */
   public IndexDefinition( DbEntityDescriptor td )
   {
      this( td, null );
   }

   /**
    * Class constructor
    * 
    * @param sIndexName
    * @param sTableName
    */
   public IndexDefinition( DbEntityDescriptor td, String sTableName )
   {
      super( td );
      
      this.vColumn = new Vector();

      setTable( sTableName );
   }

   //-------------------------------------------------------------------------//
   
   public String getTable()                    
   { 
      return sTableName; 
   }
   
   public void setTable( String sTableName ) 
   { 
      this.sTableName = sTableName; 
   }

   public void addColumn( String sColName, boolean bUnique, boolean bAscending, String sFilter )
   {
      if( sColName != null )
      {
         IndexColumnDefinition icd = new IndexColumnDefinition( sColName, bUnique, bAscending, sFilter );
         
         if( this.vColumn.contains( icd ) )    // Vector.contains(...) calls IndexColumnDefinitio..equals(...) 
            throw new IllegalArgumentException( "Colum '" + sColName + "' is already part of the index." );
         
         this.vColumn.add( icd );
      }
      else
      {
         throw new NullPointerException( "ColName can't be null" );
      }
   }

   public IndexColumnDefinition[] getColumns()
   {
      IndexColumnDefinition[] aCols = new IndexColumnDefinition[ this.vColumn.size() ];

      this.vColumn.copyInto( aCols );

      return aCols;
   }

   public void delColumn( String sColName )
   {
      int nPos = getIndex( sColName );

      if( nPos > -1 )
         this.vColumn.remove( nPos );
   }

   /**
    * Return <code>true</code> if at least one of its <code>TableColumnDefinition</code>
    * element is Unique, otherwise it returns <code>false</code>.
    *
    * @return <code>true</code> if at least one of its <code>TableColumnDefinition</code> element is Unique
    */
   public boolean isUnique()
   {
      for( int n = 0; n < this.vColumn.size(); n++ )
      {
         IndexColumnDefinition col = (IndexColumnDefinition) this.vColumn.get( n );

         if( col.isUnique() )
            return true;
      }

      return false;
   }

   /**
    * Return <code>true</code> if at least one of its <code>TableColumnDefinition</code>
    * element is Descending, otherwise it returns <code>false</code>.
    *
    * @return <code>true</code> if at least one of its <code>TableColumnDefinition</code> element is Descending
    */
   public boolean isDescending()
   {
      for( int n = 0; n < this.vColumn.size(); n++ )
      {
         IndexColumnDefinition col = (IndexColumnDefinition) this.vColumn.get( n );

         if( ! col.isAscending() )
            return true;
      }

      return false;
   }

   /**
    *
    * @param obj
    * @return
    */
   public boolean equals( Object obj )
   {
      boolean bRet = false;

      if( obj != null && obj instanceof IndexDefinition )
      {
         IndexDefinition idx = (IndexDefinition) obj;

         bRet = idx.ded.equals( this.ded )               &&
                idx.getTable().equals( this.sTableName ) &&
                idx.vColumn.equals( this.vColumn );
      }

      return bRet;
   }

   /**
    * Defined in <code>Object</code> class
    */
   public Object clone()
   {
      IndexDefinition o = (IndexDefinition) super.clone();
                      o.vColumn = (Vector) this.vColumn.clone();    // Calls 'clone()' for all its items
      return o;
   }

   //-------------------------------------------------------------------------//

   // Return the ordinal position for the column which name is sColName
   private int getIndex( String sColName )
   {
      for( int n = 0; n < this.vColumn.size(); n++ )
      {
         IndexColumnDefinition col = (IndexColumnDefinition) this.vColumn.get( n );

         if( col.getName().equals( sColName ) )
            return n;
      }

      return -1;
   }
}